import requests
from django.shortcuts import render
from django.http import JsonResponse,HttpResponse
from web.forms.file import FolderModelForm, FileModelForm
from django.views.decorators.csrf import csrf_exempt
from django.urls import reverse
import json
from web import models
from utils.tencent import cos


# http://127.0.0.1:8002/manage/1/file/
# http://127.0.0.1:8002/manage/1/file/?folder=1
def file(request, project_id):
    """文件列表 & 添加文件夹"""
    parent_object = None
    folder_id = request.GET.get('folder', '')
    if folder_id.isdecimal():
        parent_object = models.FileRepository.objects.filter(id=int(folder_id), file_type=2,
                                                             project=request.tracer.project).first()

    if request.method == 'GET':
        # 获取导航条 列表
        breadcrumb_list = []
        parent = parent_object
        while parent:
            breadcrumb_list.insert(0, {'id': parent.id, 'name': parent.name})
            parent = parent.parent
        # 获取当前项目 目录下所有的文件和文件夹
        queryset = models.FileRepository.objects.filter(project=request.tracer.project)
        if parent_object:
            # 进入某个目录
            file_object_list = queryset.filter(parent=parent_object).order_by('-file_type')
        else:
            # 根目录
            file_object_list = queryset.filter(parent__isnull=True).order_by('-file_type')
        form = FolderModelForm(request, parent_object)
        content = {
            'form': form,
            "file_object_list": file_object_list,
            "breadcrumb_list": breadcrumb_list,
            'folder_object': parent_object,
        }
        return render(request, 'file.html', content)

    fid = request.POST.get('fid', '')
    edit_object = None
    if fid.isdecimal():
        # 如果fid存在，则查询
        edit_object = models.FileRepository.objects.filter(id=int(fid), file_type=2,
                                                           project=request.tracer.project).first()
    if edit_object:
        # 如果fid对象存在，编辑文件夹
        form = FolderModelForm(request, parent_object, data=request.POST, instance=edit_object)
    else:
        # 新建文件夹
        form = FolderModelForm(request, parent_object, data=request.POST)

    if form.is_valid():
        form.instance.project = request.tracer.project
        form.instance.file_type = 2
        form.instance.update_user = request.tracer.user
        form.instance.parent = parent_object
        form.save()
        return JsonResponse({'status': True})
    return JsonResponse({'status': False, 'error': form.errors})


# http://127.0.0.1:8002/manage/1/file/delete/?fid=1
def file_delete(request, project_id):
    """删除文件"""
    fid = request.GET.get('fid')
    # 删除数据库中 文件&文件夹
    delete_object = models.FileRepository.objects.filter(id=fid, project=request.tracer.project).first()
    # 删除文件 （数据库，cos文件 删除，当前项目已使用的空间容量清除，）
    if delete_object.file_type == 1:
        # 删除文件时将容量占用清除
        request.tracer.project.user_space -= delete_object.file_size
        request.tracer.project.save()
        # cos中删除文件
        cos.delete_file(request.tracer.project.bucket, request.tracer.project.region, delete_object.key)
        delete_object.delete()
        return JsonResponse({"status": True})
    # 删除文件夹 （找到文件夹下所有文件 -> 数据库，cos文件 删除，当前项目已使用的空间容量清除，）

    total_size = 0
    folder_list = [delete_object, ]
    key_list = []
    # 遍历当前文件夹下的所有文件夹
    for folder in folder_list:
        child_list = models.FileRepository.objects.filter(project=request.tracer.project, parent=folder).order_by(
            '-file_type')
        # 遍历当前目录下的文件夹，获取其所有子孙文件夹
        for child in child_list:
            if child.file_type == 2:
                #得到目录下所有子孙文件夹
                folder_list.append(child)
            else:
                # 文件大小
                total_size += child.file_size
                # 目录下所有 要删除的 子孙 文件
                key_list.append({"Key": child.key})

    for folder in folder_list:
        print(folder.name)

    # cos 批量删除文件
    if key_list:
        cos.delete_file_list(request.tracer.project.bucket, request.tracer.project.region, key_list)
    # 删除文件时将容量占用清除
    if total_size:
        request.tracer.project.user_space -= total_size
        request.tracer.project.save()
    delete_object.delete()
    return JsonResponse({"status": True})


@csrf_exempt
def cos_credential(request, project_id):
    """上传临时凭证"""
    # 容量限制：单文件，总容量
    # 获取前端返回的参数
    file_list = json.loads(request.body.decode('utf-8'))
    # 获取单文件大小限制，单位M ：request.tracer.price_policy.per_file_size
    per_file_limit = request.tracer.price_policy.per_file_size * 1024 * 1024
    # 全部文件大小
    total_size = 0
    for item in file_list:
        # 单文件限制，获取文件字节大小b:item['size']
        if item['size'] > per_file_limit:
            msg = "单文件超出限制(最大{}M)，文件：< {} > ，请升级套餐!".format(request.tracer.price_policy.per_file_size, item['name'])
            return JsonResponse({"status": False, "error": msg})
        # 计算所有文件大小
        total_size += item['size']

    #   项目已使用空间 b    +   此次上传文件总大小 b   >   项目允许空间限制b = G*1024*1024*1024
    if request.tracer.project.user_space + total_size > request.tracer.price_policy.project_space * 1024 * 1024 * 1024:
        return JsonResponse({"status": False, "error": "容量超过限制，请升级套餐!"})

    # 获取临时凭证
    data_dict = cos.credential(request.tracer.project.bucket, request.tracer.project.region)
    return JsonResponse({"status": True, "data": data_dict})


@csrf_exempt
def file_post(request, project_id):
    """将上传成功的文件写入到数据库"""
    """ 传回的值 格式如下
    name: fileName,
    key: key,                
    file_size: fileSize,     大小
    parent:CURRENT_FOLDER_ID,父目录
    etag:data.ETag,          文件校验
    file_path:data.Location, 访问路径
    """

    form = FileModelForm(request, data=request.POST)
    if form.is_valid():
        # form.instance.file_type = 1
        # form.instance.update_user = request.tracer.user
        # instance =  form.save() #添加成功后，获取到添加的对象，无法获取choice选择项的中文
        data_dict = form.cleaned_data
        data_dict.pop('etag')  # 删除form中有，数据库中没有的字段
        data_dict.update(
            {'project': request.tracer.project, 'file_type': 1, 'update_user': request.tracer.user})  # 添加form中没有的字段
        instance = models.FileRepository.objects.create(**data_dict)

        # 项目的已使用空间更新
        request.tracer.project.user_space += data_dict['file_size']
        request.tracer.project.save()
        result = {
            'id': instance.id,
            'name': instance.name,
            'file_size': instance.file_size,
            'username': instance.update_user.username,
            'datetime': instance.update_datetime.strftime('%Y{y}%m{m}%d{d} %H:%M').format(y='年', m='月', d='日'),
            'file_type': instance.get_file_type_display(),
            'download_url': reverse('file_download',
                                    kwargs={'project_id': request.tracer.project.id, 'file_id': instance.id})
        }
        return JsonResponse({'status': True, 'data': result})
    return JsonResponse({'status': False, 'data': "文件错误"})

def file_download(request, project_id, file_id):
    """下载文件"""
    # 文件内容
    # 响应头
    # with open('xxx.jpg', mode='rb') as f:
    #     data = f.read()

    file_object = models.FileRepository.objects.filter(project_id=project_id, id=file_id).first()

    res = requests.get(file_object.file_path)
    data = res.content

    response = HttpResponse(data)
    response['Content-Disposition'] = "attachment;filename={}".format(file_object.name.encode('utf-8').decode('ISO-8859-1'))
    return response

